/*
    Android UIML

	Copyright (C) 2010  Bram Goffings (bramgoffings@gmail.com)

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public License
	as published by the Free Software Foundation; either version 2.1
	of	the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

package uiml.android.elements;

import java.util.ArrayList;

import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;

public class Part extends UimlElementWithAttributes{
	
	// TODO comment
	private ArrayList<Part> children = new ArrayList<Part>();

	private Behavior behaviour = null;
	private Content content = null;
	private Style style = null;
	private Part parent = null;
	
	// TODO comment
	private String clas = null;
	private String where = null;
	private String wherePart = null;
	
	// TODO comment
	public final static String IAM 	 = "part";
	public final static String CLASS = "class";
	public final static String WHERE = "where";
	public final static String WHERE_PART = "where-part";
	
	/**
	 * 
	 * @param node
	 */
	public Part(Element node) {
		super(node);
		process();
		
		System.out.println("Part element aangemaakt " + this.identifier + " " + this.clas);
	}
	
	/**
	 * 
	 * @param identifier
	 * @param clas
	 */
	public Part(String identifier, String clas) {
		super(null);
		
		System.out.println("Part container aangemaakt");
		
		this.identifier = identifier;
		this.clas = clas;
	}
	
	/**
	 * 
	 */
	@Override
	public void processElement(Element elem) {
		
		if(elem.getTagName().equals(Style.IAM))
			style = new Style(elem);
		else if(elem.getTagName().equals(Behavior.IAM))
			behaviour = new Behavior(elem);
		else if(elem.getTagName().equals(Content.IAM))
			content = new Content(elem);
		else if(elem.getTagName().equals(Part.IAM))
			addChild(new Part(elem));
		
	}
	
	/**
	 * 
	 */
	public void processAttributes() {
		super.processAttributes();
		
		NamedNodeMap attributes = node.getAttributes();
		
		if(attributes != null) {
			if(attributes.getNamedItem(CLASS) != null)
				setClas(attributes.getNamedItem(CLASS).getNodeValue());
			else if(attributes.getNamedItem(WHERE) != null)
				setWhere(attributes.getNamedItem(WHERE).getNodeValue());
			else if(attributes.getNamedItem(WHERE_PART) != null)
				setWherePart(attributes.getNamedItem(WHERE_PART).getNodeValue());
		}
	}
	
	public String toString() {
		
		String returnString = "";
			
		returnString += "    <part";
		
		if(identifier!=null)
			returnString += " id=\"" + identifier + "\" ";
		if(source!=null)
			returnString += " source=\"" + source + "\" ";
		if(how!=null && !how.equalsIgnoreCase("replace"))
			returnString += " how=\"" + how + "\" ";
		if(export!=null && !export.equalsIgnoreCase("optional"))
			returnString += " export=\"" + export + "\" ";
		if(clas!=null)
			returnString += " class=\"" + clas + "\" ";
		if(where!=null)
			returnString += " where=\"" + where + "\" ";
		if(wherePart!=null)
			returnString += " where-part=\"" + wherePart + "\" ";
		
		if(style==null && behaviour==null && content==null && children.size()==0)
			returnString += "/>\n";
		else
		{
			returnString += ">\n";
			
			if(style!=null)
				returnString += "  " + style.toString() + "\n";
			if(behaviour!=null)
				returnString += "  " + behaviour.toString() + "\n";
			if(content!=null)
				returnString += "  " + content.toString() + "\n";
			
			for(Part part : children)
				returnString += "  " + part.toString() + "\n";
			
			returnString += "      </part>\n";
		}		
		
		return returnString;
	}
	
	public Part searchPart(String identifier) {
		Part top = findTopPart();
		return top.getPartById(identifier);
	}
	
	public Part getPartById(String identifier) {
		
		Part result = null;
		boolean found = false;
		
		if(this.getIdentifier().equals(identifier))
			result = this;
		else if(children.size()>0) {
			for(int i=0; i<children.size() && !found; i++){
				result =  children.get(i).getPartById(identifier);
				
				if(result != null)
					found = true;
			}
		}
		return result;
	}
	
	private Part findTopPart() {
		Part temp = this;
		
		while(temp.getParent() != null)
			temp = temp.getParent();
		
		return temp;
	}

	/**
	 * 
	 * @param part
	 */
	public void addChild(Part part) {
		part.setParent(this);
		children.add(part);
	}
	
	/**
	 * 
	 * @param parent
	 */
	public void setParent(Part parent) {
		this.parent = parent;
	}

	/**
	 * 
	 * @return
	 */
	public Part getParent() {
		return parent;
	}
	
	/**
	 * 
	 * @return
	 */
	public boolean hasSubParts() {
		return children.size() != 0;
	}
	
	/**
	 * 
	 * @return
	 */
	public ArrayList<Part> getSubParts() {
		return children;
	}

	/**
	 * 
	 * @param clas
	 */
	public void setClas(String clas) {
		this.clas = clas;
	}

	/**
	 * 
	 * @return
	 */
	public String getClas() {
		return clas;
	}

	/**
	 * 
	 * @return
	 */
	public ArrayList<Property> getProperties() {
		return style.getProperties();
	}

	/**
	 * 
	 * @param wherePart
	 */
	public void setWherePart(String wherePart) {
		this.wherePart = wherePart;
	}

	/**
	 * 
	 * @return
	 */
	public String getWherePart() {
		return wherePart;
	}

	/**
	 * 
	 * @param where
	 */
	public void setWhere(String where) {
		this.where = where;
	}

	/**
	 * 
	 * @return
	 */
	public String getWhere() {
		return where;
	}

	/**
	 * @param behaviour the behaviour to set
	 */
	public void setBehaviour(Behavior behaviour) {
		this.behaviour = behaviour;
	}

	/**
	 * @return the behaviour
	 */
	public Behavior getBehaviour() {
		return behaviour;
	}

	/**
	 * @param content the content to set
	 */
	public void setContent(Content content) {
		this.content = content;
	}

	/**
	 * @return the content
	 */
	public Content getContent() {
		return content;
	}

	/**
	 * @param style the style to set
	 */
	public void setStyle(Style style) {
		this.style = style;
	}

	/**
	 * @return the style
	 */
	public Style getStyle() {
		return style;
	}
	
	
	/**
	 * @return the children
	 */
	public ArrayList<Part> getChildren() {
		return children;
	}

	/**
	 * @param children the children to set
	 */
	public void setChildren(ArrayList<Part> children) {
		this.children = children;
	}

}
